<?php
/**********************
**intellistrip_client_unit_tests.inc
**Date Created: 4/13/2009
**Copyright 2009 Tomorrow Tech Industries
**Contact: RPITomorrowTech@gmail.com
**********************/

require_once('intellistrip_client.inc');
require_once('shared/unit_test.inc');

class IntellistripClientUnitTest extends UnitTest
{
	function getClient()
	{
		$client = new IntellistripClient(array('serverPath' => 'software_intellistrip/xml_rpc_server_hardware.php'));
		return $client;
	}
	
	static function testIntellistripClient()
	{
		$unitTester = new IntellistripClientUnitTest();
		//If the test fails, run a second time with verbose output
		if( !$unitTester->runTest() )
		{
			echo "<BR>\n";
			echo "<BR>\n";
			echo "<BR>\n";
			echo "<BR>\n";
			echo "<H1>Verbose analysis</H1>";
			echo "<BR>\n";
			echo "<BR>\n";

			$oldDebugging = IntellistripActions::getDebugging();				
			IntellistripActions::setDebugging(true);		
			$unitTester->runTest();
			IntellistripActions::setDebugging($oldDebugging);
			return false;
		}
		else
		{
			return true;
		}
	}

	public function runTest()
	{
		$tests = array();
		
		//TODO: make more granular by using arguments
		//Add tests
		array_push($tests, array("<H2>getIntellistripInformation()</H2>"));
		array_push($tests, array('getIntellistripInformation', true, array()));

		array_push($tests, array("<H2>getPortPower: positive testing</H2>"));
		array_push($tests, array('getPortPowerPositive', true, array()));
		array_push($tests, array("<H2>getPortPower: negative testing</H2>"));
		array_push($tests, array('getPortPowerNegative', true, array()));
		array_push($tests, array("<H3>getPortPower: bad password</H2>"));
		array_push($tests, array('getPortPowerBadPassword', true, array()));


		/*********
		A heavy duty stress test for setPortPower
		Does a number of corner cases and other things
		Designed to be a general stress test to the system
		*********/
		//Positive testing
		array_push($tests, array('<H2>setPortPower(): positive testing</H2>'));
		//Full off
		array_push($tests, array('<H3>Full off</H3>'));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 0, 'powerLevel' => INTELLISTRIP_POWER_OFF)));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 2, 'powerLevel' => INTELLISTRIP_POWER_OFF)));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 4, 'powerLevel' => INTELLISTRIP_POWER_OFF)));
		//Partially on
		array_push($tests, array('<H3>Partially on</H3>'));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 0, 'powerLevel' => 13)));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 2, 'powerLevel' => 99)));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 4, 'powerLevel' => 1)));
		//Full on
		array_push($tests, array('<H3>Full on</H3>'));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 0, 'powerLevel' => INTELLISTRIP_POWER_ON)));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 2, 'powerLevel' => INTELLISTRIP_POWER_ON)));
		array_push($tests, array('setPortPower', true, array('portId' => INTELLISTRIP_PORT_BASE + 4, 'powerLevel' => INTELLISTRIP_POWER_ON)));


		//Negative testing
		array_push($tests, array('<H2>setPortPower(): negative testing</H2>'));
		//bad port IDs
		array_push($tests, array('<H3>Bad port ID</H3>'));
		//All command
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_ALL, 'powerLevel' => INTELLISTRIP_POWER_ON)));
		//Slightly above allowed
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_BASE + 5, 'powerLevel' => INTELLISTRIP_POWER_ON)));
		//Far above allowed
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_BASE + 75, 'powerLevel' => INTELLISTRIP_POWER_ON)));

		//bad power levels
		array_push($tests, array('<H3>Bad power level</H3>'));
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_ALL, 'powerLevel' => INTELLISTRIP_POWER_ON + 1)));
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_ALL, 'powerLevel' => INTELLISTRIP_POWER_ON + 232)));
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_ALL, 'powerLevel' => INTELLISTRIP_POWER_OFF - 1)));
		array_push($tests, array('setPortPower', false, array('portId' => INTELLISTRIP_PORT_ALL, 'powerLevel' => INTELLISTRIP_POWER_OFF - 42)));

		//Make sure proper failure for bad password
		array_push($tests, array('<H3>Bad password</H3>'));
		array_push($tests, array('setPortPowerNegativeBadPassword', true, array()));
		
		//This feature fails testing and has been dropped
		array_push($tests, array('<H2>changePassword(): positive</H2>'));
		array_push($tests, array('changePasswordPositive', true, array()));
		array_push($tests, array('<H2>changePassword(): negative</H2>'));
		array_push($tests, array('changePasswordNegative', true, array()));		

		echo "<H1>Intellistrip Client Testing</H1>\n";

		return $this->runTests($tests);
	}
	
	function getIntellistripInformation($args, &$error)
	{
		$strip = $this->getClient();

		//Test: get information
		$rc = $strip->getIntellistripInformation($vendorName, $modelNumber, 
										$modelVersion, $serialNumber,
										$numberPorts, $state);
		echo "rc: " . errorString($rc);
		if( TT_FAILED($rc) )
		{
			$error = "Call failed: " . $error = $strip->getLastError();
			return false;
		}
		echo "<BR>";

		echo "vendorName: " . $vendorName . "\n";
		echo "<BR>\n";

		echo "modelNumber: " . $modelNumber . "\n";
		echo "<BR>\n";

		echo "modelVersion: " . $modelVersion . "\n";
		echo "<BR>\n";

		echo "serialNumber: " . $serialNumber . "\n";
		echo "<BR>\n";

		echo "numberPorts: " . $numberPorts . "\n";
		echo "<BR>\n";

		echo "state: " . $state . "\n";
		echo "<BR>\n";

		return true;
	}
	
	function getPortPowerPositive($args, &$error)
	{
		$succeeded = true;
		$strip = $this->getClient();
		$error = '';

		//Test: get information
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 0, true, -1);
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 1, true, -1);
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 2, true, -1);
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 3, true, -1);
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 4, true, -1);
		
		return $succeeded;
	}

	function getPortPowerNegative($args, &$error)
	{
		$succeeded = true;
		$strip = $this->getClient();

		echo "<H3>getPortPower: bad indexes</H3>\n";
		//Invalid ID's
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_ALL, false, -1);
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 5, false, -1);
		$succeeded &= $this->testGetPortPower(INTELLISTRIP_PORT_BASE + 75, false, -1);

		$this->markTestCase($succeeded, true, $strip->getLastError());

		return $succeeded;
	}

	function getPortPowerBadPassword($args, &$error)
	{
		$strip = $this->getClient();

		$strip->setServerPassword('notthepassword');
		$rc = $strip->getPortPower(INTELLISTRIP_PORT_BASE, $powerLevel);
		echo "rc: " . errorString($rc);
		echo "<BR>";
		if( $rc != TT_ACCESS )
		{
			$error = $strip->getLastError();
			return false;
		}
		return true;
	}

	function testGetPortPower($portId, $passExpected, $expectedLevel)
	{
		$strip = $this->getClient();

		$error = '';
		$succeeded = true;
		echo "<H4>getPortPower (port " . $portId . ")</H4>\n";
		$strip->clearLastError();
		$rc = $strip->getPortPower($portId, $powerLevel);
		echo "rc: " . errorString($rc);
		echo "<BR>";
		if( TT_FAILED($rc) )
		{
			$succeeded = false;
			$error = $strip->getLastError();
		}
		else
		{
			if( $expectedLevel >= 0 && $expectedLevel != $powerLevel )
			{
				$succeeded = false;
				$error = "Power level does not match, wanted: " . $expectedLevel . ", got: " . $powerLevel;
			}
			else
			{
				echo "powerLevel: " . $powerLevel . "\n";
				echo "<BR>\n";
			}
		}
		if( !$passExpected )
		{
			$succeeded = !$succeeded;
			if( !$succeeded )
			{
				$error = 'Expected fail';		
			}
		}
		$this->markTestCase($succeeded, true, $error);

		return $succeeded;
	}
	
	function setPortPowerNegativeBadPassword($args, &$error)
	{
		$strip = $this->getClient();
		
		$strip->setServerPassword('notthepassword');
		$rc = $strip->setPortPower(1, INTELLISTRIP_POWER_ON);
		echo "rc: " . errorString($rc);
		echo "<BR>";
		//We should get an access denied style code
		if( $rc == TT_ACCESS )
		{
			return true;
		}
		else if( TT_FAILED($rc) )
		{
			$error = 'expected TT_ACCESS, message: ' . $strip->getLastError();
			return false;
		}
		else
		{
			$error = 'expected TT_ACCESS';
			return false;
		}
		return true;
	}
	
	/************
	FIXME: make this into the direct called function
	************/
	function setPortPower($args, &$error)
	{
		if( !is_array($args) )
		{
			$error = "Bad input<BR>";
			return TT_INVALID_INPUT;
		}
			
		$portId = $args['portId'];
		$powerLevel = $args['powerLevel'];
		
		$strip = $this->getClient();

		//Verify if was actually set to value required
		$rc = $strip->getPortPower($portId, $oldPowerLevel);
		if( TT_FAILED($rc) )
		{
			$error = "getPortPower() failed: " . $strip->getLastError();
			return false;
		}
		$rc = $strip->setPortPower($portId, $powerLevel);
		echo "rc: " . errorString($rc);
		echo "<BR>";
		if( TT_FAILED($rc) )
		{
			$error = "setPortPower() failed: " . $strip->getLastError();
			return false;
		}
		//Verify if was actually set to value required
		$rc = $strip->getPortPower($portId, $powerLevelNew);
		if( TT_FAILED($rc) )
		{
			$error = "getPortPower() failed: " . $strip->getLastError();
			return false;
		}
		echo "Queried power level: " . $powerLevelNew . "<BR>\n";
		if( $powerLevel != $powerLevelNew )
		{
			$error = "Final level does not equal requested ($powerLevel != $powerLevelNew)<BR>\n";
			return false;
		}

		return true;
	}

	/************
	Sanity tests for trying to change the password
	$args
		None
	************/
	function changePasswordPositive($args, &$error)
	{
		$succeeded = true;
		$strip = $this->getClient();

		$lastSucceeded = true;
		$strip->clearLastError();
		$oldPassword = $strip->getServerPassword();
		$newPassword = 'thenewpassword';
		
		$rc = $strip->changePassword($newPassword);
		echo "rc: " . errorString($rc);
		echo "<BR>";
		if( TT_FAILED($rc) )
		{
			$error = 'Failed to change password: ' . $strip->getLastError();
			return false;
		}
		
		//Make sure object was updated
		if( $strip->getServerPassword() != $newPassword )
		{
			$error = 'Client did not change password';
			return false;
		}
		
		//Try a sample cal
		$rc = $strip->getPortPower(INTELLISTRIP_PORT_BASE, $powerLevel);
		if( TT_FAILED($rc) )
		{
			$error = 'Could not get port power';
			$strip->changePassword($newPassword);
			return false;
		}
		
		return true;
	}

	/************
	Sanity tests for failing to change the password
	$args
		None
	************/
	function changePasswordNegative($args, &$error)
	{
		$strip = $this->getClient();

		$lastSucceeded = true;
		$strip->clearLastError();
		$oldPassword = $strip->getServerPassword();
		$newPassword = 'thenewpassword';
		
		$strip->setServerPassword('notthepassword');
		$rc = $strip->changePassword($newPassword);
		echo "rc: " . errorString($rc);
		echo "<BR>";
		if( TT_SUCCEEDED($rc) )
		{
			$error = 'server should have rejected access password';
			return false;
		}
		if( $rc != TT_ACCESS )
		{
			$error = 'expected TT_ACCESS failure';
			return false;
		}
		
		//Make sure object was not updated
		if( $strip->getServerPassword() != $oldPassword )
		{
			$error = 'local password cache changed despite failure';
			return false;
		}
		
		//Try a sample call with new password to make sure it didn't change
		$strip->setServerPassword($newPassword);
		$rc = $strip->getPortPower(INTELLISTRIP_PORT_BASE, $powerLevel);
		if( TT_SUCCEEDED($rc) )
		{
			$error = "granted access when shouldn't have (used getPortPower)";
			return false;
		}

		//Try a sample call with old password to make sure it didn't change
		$strip->setServerPassword($oldPassword);
		$rc = $strip->getPortPower(INTELLISTRIP_PORT_BASE, $powerLevel);
		if( TT_FAILED($rc) )
		{
			$error = 'could not execute with old password (used getPortPower)';
			return false;
		}
		
		return true;
	}
}
?>
